package khmt.lvtn.dhbk.comment;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.StringTokenizer;

import khmt.lvtn.dhbk.model.CommonModel;
import khmt.lvtn.dhbk.model.SentimentModel;
import khmt.lvtn.dhbk.model.process.MainProcess;


/**
 * 
 * @author Live Slowly
 *
 */
class VerbListAndAdjListModifiedForSuperEntity {
	private ArrayList<Verb> verbList;
	private ArrayList<Adjective> adjList;

	public VerbListAndAdjListModifiedForSuperEntity() {
		// TODO Auto-generated constructor stub
		setVerbList(new ArrayList<Verb>());
		setAdjList(new ArrayList<Adjective>());
	}

	public void setVerbList(ArrayList<Verb> verbList) {
		this.verbList = verbList;
	}

	public ArrayList<Verb> getVerbList() {
		return verbList;
	}

	public void setAdjList(ArrayList<Adjective> adjList) {
		this.adjList = adjList;
	}

	public ArrayList<Adjective> getAdjList() {
		return adjList;
	}
}

public class Comment {
	private String origianlComment = "";
	private String commentAfterReplacePronounByEntity;
	private ArrayList<Word> superEntiList;

	private ArrayList<Word> entiList;
	private ArrayList<Word> proList;
	private ArrayList<Sentence> sentList;
	private ArrayList<String> superEntiTextList;
	private Hashtable<String, VerbListAndAdjListModifiedForSuperEntity> superEntityAndWordsModified;
	private Hashtable<String, ArrayList<Word>> superEntityAndEntitiList;
	private Result result;

	public Comment(String originalComment) {

		if (originalComment == null) {
			originalComment = "";
		}
		originalComment = originalComment.toLowerCase();
		this.origianlComment = originalComment;
		this.commentAfterReplacePronounByEntity = this.origianlComment;
		this.superEntiList = new ArrayList<Word>();
		this.entiList = new ArrayList<Word>();
		this.proList = new ArrayList<Word>();
		this.superEntityAndWordsModified = new Hashtable<String, VerbListAndAdjListModifiedForSuperEntity>();
		this.superEntiTextList = new ArrayList<String>();
		this.superEntityAndEntitiList = new Hashtable<String, ArrayList<Word>>();
		this.result = new Result();
		boolean flag = false;
		// done test
		setSentList();
		if (this.sentList.size() == 1) {
			MainProcess maiProcess = new MainProcess();
			String sent = this.sentList.get(0).getSentence();
			if (maiProcess.isQuestion(sent) == true) {
				flag = true;
				setSuperEntities();
				setEntiList();
				this.setSuperEntiTextList();
				this.result.setOneOrMultiEntity(1);
				this.result.setSentimentForOneCase(0);
			}
		}

		if (flag == false) {
			setSuperEntities();
			setEntiList();
			setProList();
			setCommentAfterReplacePronounbyEntity(this.entiList, this.proList);
			this.sentList = new ArrayList<Sentence>();
			setSentList();
			setResult();
		}
		
	}

	private void setModeForSentList() {
		for (int i = 0; i < this.sentList.size(); i++) {
			this.sentList.get(i).setModeOneOrMultiEntities(2);
		}
	}

	private void setResult()  {
		// TODO Auto-generated method stub
		/**
		 * Run for all entity
		 */
		 this.setSuperEntiTextList();
		 if(this.superEntiTextList == null ||(this.superEntiTextList!=null &&
		 this.superEntiTextList.size()<=1)){
			 System.out.println("Comment.setResult()");
			 this.result.setOneOrMultiEntity(1);
			 setResultForOneSuperEntityCase();
		 }
		 else if(this.superEntiTextList.size() >= 2){
			 this.setSuperEntiTextList();
			 this.result.setOneOrMultiEntity(2);
			 setResultForMultSuperEntityCase();
		 }
	}

	private void setResultForMultSuperEntityCase() {
		this.setAllKeyForHashTableSuperAndEntiList();
		this.setSuperEntityAndEntiList();
		this.setAllKeyForHashTableSuperAndModifiedWord();
		this.setAdjListAndVerbListForSuperEntiHashtable();
		this.setScoreForEachSuperEntity();
	}


	private void setScoreForEachSuperEntity() {
		if (this.superEntityAndWordsModified == null) {
			return;
		}
		Enumeration<String> superEntiList = this.superEntityAndWordsModified
				.keys();
		while (superEntiList.hasMoreElements()) {
			String superEntity = superEntiList.nextElement();
			float sentiment = 0;
			float absSentiment = 0;
			SentimentModel sentimentForSuperEntity = new SentimentModel(
					superEntity, sentiment);
			ArrayList<Adjective> adjList = this.superEntityAndWordsModified
					.get(superEntity).getAdjList();
			ArrayList<Verb> verbList = this.superEntityAndWordsModified.get(
					superEntity).getVerbList();
			for (int i = 0; i < adjList.size(); i++) {
				sentiment += adjList.get(i).getFinalSentiment();
				absSentiment += Math.abs(adjList.get(i).getFinalSentiment());
			}
			for (int i = 0; i < verbList.size(); i++) {
				sentiment += verbList.get(i).getFinalSentiment();
				absSentiment += Math.abs(verbList.get(i).getFinalSentiment());
			}
			if(absSentiment == 0){
				absSentiment = 1;
			}
			sentimentForSuperEntity.setScore(sentiment/absSentiment);
			this.result.setSentimentForMultCase(sentimentForSuperEntity);
		}
	}

	private void setAdjListAndVerbListForSuperEntiHashtable() {
		if (this.superEntityAndEntitiList != null) {
			Enumeration<String> keyOfSuperAndEntiListHashTable = this.superEntityAndWordsModified
					.keys();
			while (keyOfSuperAndEntiListHashTable.hasMoreElements()) {
				String key = keyOfSuperAndEntiListHashTable.nextElement();
				ArrayList<Word> entiList = this.superEntityAndEntitiList
						.get(key);	
				if (entiList == null) {
					continue;
				} else if (entiList.size() <= 0) {
					continue;
				}
				ArrayList<Adjective> adjList = this.superEntityAndWordsModified
						.get(key).getAdjList();
				ArrayList<Verb> verbList = this.superEntityAndWordsModified
						.get(key).getVerbList();
				if (this.sentList != null) {
					for (int i = 0; i < this.sentList.size(); i++) {
						for (int j = 0; j < this.sentList.get(i).getAdjList()
								.size(); j++) {
							String entityOfAdjective = this.sentList.get(i)
									.getAdjList().get(j)
									.getEntityBeenModified().toLowerCase()
									.replaceAll(" ", "");
							
							for(int k=0; k<entiList.size(); k++){
								String entity = entiList.get(k).getWord().replace(" ", "").toLowerCase();
								if(entity.equals(entityOfAdjective)){
									adjList.add(this.sentList.get(i).getAdjList()
											.get(j));
									break;
								}
							}
						}
						for (int j = 0; j < this.sentList.get(i).getVerbList()
								.size(); j++) {
							String entityOftVerb = this.sentList.get(i)
									.getVerbList().get(j)
									.getEntityBeenModified().toLowerCase()
									.replaceAll(" ", "");
		
							
							for(int k=0; k<entiList.size(); k++){
								String entity = entiList.get(k).getWord().replace(" ", "").toLowerCase();
								if(entity.equals(entityOftVerb)){
									verbList.add(this.sentList.get(i).getVerbList()
											.get(j));
									break;
								}
							}
						}
					}
				}
			}
		}
	}

	private void setAllKeyForHashTableSuperAndEntiList() {
		if (this.superEntiTextList != null) {
			if (this.superEntiTextList.size() > 0) {
				for (int i = 0; i < this.superEntiTextList.size(); i++) {
					String superEntity = this.superEntiTextList.get(i)
							.toLowerCase().replaceAll(" ", "");
					this.superEntityAndEntitiList.put(superEntity,
							new ArrayList<Word>());
				}
			}
		}
	}

	private void setAllKeyForHashTableSuperAndModifiedWord() {
		if (this.superEntiTextList != null) {
			if (this.superEntiTextList.size() > 0) {
				for (int i = 0; i < this.superEntiTextList.size(); i++) {
					String superEntity = this.superEntiTextList.get(i)
							.toLowerCase().replaceAll(" ", "");
					this.superEntityAndWordsModified.put(superEntity,
							new VerbListAndAdjListModifiedForSuperEntity());
				}
			}
		}
	}

	private void setResultForOneSuperEntityCase() {
		// TODO Auto-generated method stub
		this.result.setSentimentForOneCase(0);
		if (this.sentList != null) {
			if (this.sentList.size() > 0) {
				for (int i = 0; i < this.sentList.size(); i++) {
					if (this.sentList.get(i).getAdjList() != null) {
						if (this.sentList.get(i).getAdjList().size() > 0) {
							ArrayList<Adjective> adjList = this.sentList.get(i)
									.getAdjList();
							System.out.println(adjList.size());
							for (int j = 0; j < adjList.size(); j++) {
								if(adjList.get(j).getWord().equals("có")){
									continue;
								}
								this.result.setSentimentForOneCase(this.result
										.getSentimentForOneCase()
										+ adjList.get(j).getFinalSentiment());
								System.out
										.println("Comment.setResultForOneSuperEntityCase() "+adjList.get(j).getWord()
												+adjList.get(j).getFinalSentiment());
							}
						}
					}
					if (this.sentList.get(i).getVerbList() != null) {
						if (this.sentList.get(i).getVerbList().size() > 0) {
							ArrayList<Verb> verbList = this.sentList.get(i)
									.getVerbList();
							for (int j = 0; j < verbList.size(); j++) {
								this.result.setSentimentForOneCase(this.result
										.getSentimentForOneCase()
										+ verbList.get(j).getFinalSentiment());
							}
						}
					}
				}
				float absOfAllScore = 0;
				for (int i = 0; i < this.sentList.size(); i++) {
					ArrayList<Adjective> adjList = this.sentList.get(i)
							.getAdjList();
					ArrayList<Verb> verbList = this.sentList.get(i)
							.getVerbList();
					for (int j = 0; j < adjList.size(); j++) {
						absOfAllScore += Math.abs(adjList.get(j)
								.getFinalSentiment());
					}
					for (int j = 0; j < verbList.size(); j++) {
						absOfAllScore += Math.abs(verbList.get(j)
								.getFinalSentiment());
					}
				}

				if (absOfAllScore == 0) {
					absOfAllScore = 1;
				}
				this.result.setSentimentForOneCase(this.result
						.getSentimentForOneCase() / absOfAllScore);
			}
		}
	}

	private void setSuperEntities() {
		if (this.superEntiList == null) {
			this.superEntiList = new ArrayList<Word>();
		}
		MainProcess getWord = new MainProcess();
		ArrayList<CommonModel> sentModel = getWord
				.processGetEntity(this.origianlComment);
		changeArrayFromCommonModelToWord(sentModel, this.superEntiList);
	}

	private void setEntiList() {
		if (this.entiList == null) {
			this.entiList = new ArrayList<Word>();
		}
		MainProcess getEntiList = new MainProcess();
		changeArrayFromCommonModelToWord(
				getEntiList.processGetEntityAndProperty(this.origianlComment),
				this.entiList);
	}

	private void setProList() {
		if (this.proList == null) {
			this.proList = new ArrayList<Word>();
		}
		MainProcess getPronoun = new MainProcess();
		changeArrayFromCommonModelToWord(
				getPronoun.processGetPronoun(this.origianlComment),
				this.proList);
	}

	private void setCommentAfterReplacePronounbyEntity(
			ArrayList<Word> entiList, ArrayList<Word> proList) {
		if (entiList != null && proList != null) {
			if (entiList.size() > 0 && proList.size() > 0) {
				String temp = this.origianlComment;
				for (int i = 0; i < proList.size(); i++) {
					int positionOfEntityReplaceForPronoun = -1;
					for (int j = 0; j < entiList.size(); j++) {
						int positionOfEntity = entiList.get(j).getPosition();
						if (positionOfEntity < proList.get(i).getPosition()) {
							positionOfEntityReplaceForPronoun = j;
						} else {
							break;
						}
					}
					if (positionOfEntityReplaceForPronoun != -1) {
						temp = temp.substring(0, proList.get(i).getPosition())
								+ (temp.substring(proList.get(i).getPosition()))
										.replaceFirst(
												proList.get(i).getWord(),
												entiList.get(
														positionOfEntityReplaceForPronoun)
														.getWord());
					}
					positionOfEntityReplaceForPronoun = -1;
				}
				this.commentAfterReplacePronounByEntity = temp;
			}
		}
	}

	private void setSentList() {
		if (this.sentList == null) {
			this.sentList = new ArrayList<Sentence>();
		}
		StringTokenizer stk = new StringTokenizer(commentAfterReplacePronounByEntity,"?.!");
		ArrayList<String> sentList = new ArrayList<String>();
		while(stk.hasMoreElements()){
			String sent = stk.nextToken();
			if(isQuestion(sent)){
				continue;
			}
			if((!sent.equals("")) && (!sent.equals(null))){
				this.sentList.add(new Sentence(sent));
			}
		}
	}

	private boolean isQuestion(String s) {
		if(this.origianlComment.contains("?")){
			return true;
		}
		return false;
	}

	public static void changeArrayFromCommonModelToWord(
			ArrayList<CommonModel> comModel, ArrayList<Word> wl) {
		if (comModel != null) {
			if (comModel.size() != 0) {
				if (wl == null) {
					wl = new ArrayList<Word>();
				}
				for (int i = 0; i < comModel.size(); i++) {
					Word w = new Word(comModel.get(i).getWordCommon(), comModel
							.get(i).getLocation());
					wl.add(w);
				}
			}
		}
	}

	public Result getResult() {
		return this.result;
	}

	private void setSuperEntityAndEntiList() {
		if (this.superEntityAndEntitiList == null) {
			this.superEntityAndEntitiList = new Hashtable<String, ArrayList<Word>>();
		}

		if (this.sentList != null) {
			if (this.sentList.size() > 0) {
				for (int i = 0; i < this.sentList.size(); i++) {
					Sentence sent = this.sentList.get(i);
					ArrayList<Word> superEntiList = sent.getSuperEntites();
					ArrayList<Word> entiList = sent.getEntiList();
					if (superEntiList == null || entiList == null) {
						continue;
					} else if (superEntiList.size() == 0
							|| entiList.size() == 0) {
						continue;
					}
					for (int j = 0; j < entiList.size(); j++) {
						int locationOfSuperEntiList = -1;
						for (int k = 0; k < superEntiList.size(); k++) {
							if (entiList.get(j).getPosition() >= superEntiList
									.get(k).getPosition()) {
								locationOfSuperEntiList = k;
							} else {
								break;
							}
						}
						String key = "";
						if (locationOfSuperEntiList != -1) {
							key = superEntiList.get(locationOfSuperEntiList)
									.getWord().toLowerCase()
									.replaceAll(" ", "");
						} else {
							key = this.superEntiList.get(0).getWord()
									.toLowerCase().replaceAll(" ", "");
						}
						if (this.superEntityAndEntitiList.containsKey(key) == true) {
							ArrayList<Word> value = null;
							if (this.superEntityAndEntitiList.get(key) == null) {
								value = new ArrayList<Word>();
							} else {
								value = this.superEntityAndEntitiList.get(key);
							}
							value.add(entiList.get(j));
							this.superEntityAndEntitiList.put(key, value);
						} else {
							ArrayList<Word> value = new ArrayList<Word>();
							value.add(entiList.get(j));
							this.superEntityAndEntitiList.put(key, value);
						}
						locationOfSuperEntiList = -1;
					}
				}
			}
			
		}
	}

	public Hashtable<String, VerbListAndAdjListModifiedForSuperEntity> getSuperEntityAndWordsModified() {
		return superEntityAndWordsModified;
	}

	private void setSuperEntiTextList() {
		if (this.superEntiTextList == null) {
			this.superEntiTextList = new ArrayList<String>();
		}
		if (this.superEntiList != null) {
			if (this.superEntiList.size() > 0) {
				String enti = this.superEntiList.get(0).getWord();
				this.superEntiTextList.add(enti);
				for (int i = 1; i < this.superEntiList.size(); i++) {
					boolean exist = false;
					for (int j = 0; j < this.superEntiTextList.size(); j++) {
						if (this.superEntiList
								.get(i)
								.getWord()
								.toLowerCase()
								.replaceAll(" ", "")
								.compareTo(
										this.superEntiTextList.get(j)
												.toLowerCase()
												.replaceAll(" ", "")) == 0) {
							exist = true;
							break;
						}
					}
					if (exist == false) {
						this.superEntiTextList.add(this.superEntiList.get(i)
								.getWord());
					}
					exist = false;
				}
			}
		}
		for(int i=0; i<this.superEntiTextList.size(); i++){
			if(this.superEntiTextList.get(i).equals("")){
				this.superEntiTextList.remove(i);
			}
		}
	}

	public ArrayList<String> getSuperEntiTextList() {
		return superEntiTextList;
	}

	public Hashtable<String, ArrayList<Word>> getSuperEntityAndEntitiList() {
		return superEntityAndEntitiList;
	}
}